package org.aphelie.torg.ruler.internal.ui.editor.character;




import org.aphelie.torg.ruler.core.IBaseModel;
import org.aphelie.torg.ruler.core.IModelChangeProvider;
import org.aphelie.torg.ruler.core.IModelChangedEvent;
import org.aphelie.torg.ruler.core.character.CharacterRegistry;
import org.aphelie.torg.ruler.core.character.ICharacterBase;
import org.aphelie.torg.ruler.core.character.ICharacterModelBase;
import org.aphelie.torg.ruler.core.character.ICharacterSketch;
import org.aphelie.torg.ruler.internal.core.character.CharacterBase;
import org.aphelie.torg.ruler.internal.ui.TGRPlugin;
import org.aphelie.torg.ruler.internal.ui.TGRUIMessages;
import org.aphelie.torg.ruler.internal.ui.editor.FormEntryAdapter;
import org.aphelie.torg.ruler.internal.ui.editor.FormLayoutFactory;
import org.aphelie.torg.ruler.internal.ui.editor.TGRFormPage;
import org.aphelie.torg.ruler.internal.ui.editor.TGRSection;
import org.aphelie.torg.ruler.internal.ui.editor.character.validation.ControlValidationUtility;
import org.aphelie.torg.ruler.internal.ui.editor.character.validation.TextValidator;
import org.aphelie.torg.ruler.internal.ui.parts.FormEntry;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.forms.widgets.TableWrapData;


public class SketchSection extends TGRSection {
    
    private FormEntry fAgeEntry;
    
    private TextValidator fAgeEntryValidator;
    
    private ICharacterModelBase fModel;
    
    public SketchSection(TGRFormPage page, Composite parent) {
        super(page, parent, Section.DESCRIPTION);
        createClient(getSection(), page.getEditor().getToolkit());
    }
    
    protected void createClient(Section section, FormToolkit toolkit) {
        section.setText(TGRUIMessages.CharacterEditor_SketchSection_title);
        section.setLayout(FormLayoutFactory.createClearTableWrapLayout(true, 2));
        TableWrapData data = new TableWrapData(TableWrapData.FILL_GRAB);
        section.setLayoutData(data);
        
        section.setDescription(TGRUIMessages.CharacterEditor_SketchSection_desc);
        Composite client = toolkit.createComposite(section);
        client.setLayout(FormLayoutFactory.createSectionClientTableWrapLayout(false, 3));
        section.setClient(client);
        
        IActionBars actionBars = getPage().getTGREditor().getEditorSite().getActionBars();
        
        createAgeEntry(client, toolkit, actionBars);
        
        //createSpecificControls(client, toolkit, actionBars);
        toolkit.paintBordersFor(client);
        
        addListeners();
    }
    
    
    
    protected ICharacterBase getCharacterBase() {
        IBaseModel model = getPage().getTGREditor().getAggregateModel();
        return ((ICharacterModelBase) model).getCharacterBase();
    }
    
    protected ICharacterModelBase getModelBase() {
        if (fModel == null) {
            fModel = CharacterRegistry.findModel(getProject());
        }
        return fModel;
    }
    
    /**
     * Age entry creation
     */
    private void createAgeEntry(Composite client, FormToolkit toolkit, IActionBars actionBars) {
        fAgeEntry = new FormEntry(client, toolkit, TGRUIMessages.CharacterEditor_age, null, false);
        fAgeEntry.setFormEntryListener(new FormEntryAdapter(this, actionBars) {

            public void textValueChanged(FormEntry entry) {
                try {
                    ICharacterBase cb = getCharacterBase();
                    ICharacterSketch rep = cb.getSketch();
                    getCharacterBase().getSketch().setAge(entry.getValue());
                } catch (CoreException e) {
                    TGRPlugin.logException(e);
                }
            }
        });
        fAgeEntry.setEditable(isEditable());

        fAgeEntryValidator = new TextValidator(getManagedForm(), fAgeEntry.getText(), getProject(), true) {

            protected boolean validateControl() {
                return validateAgeEntry();
            }
        };
    }
    
    private boolean validateAgeEntry() {
        return ControlValidationUtility.validateTranslatableField(fAgeEntry.getText().getText(), fAgeEntryValidator, getModelBase(), getProject());
    }
    
    
    
    public void commit(boolean onSave) {
        fAgeEntry.commit();
        super.commit(onSave);
    }
    
    public void modelChanged(IModelChangedEvent e) {
        if (e.getChangeType() == IModelChangedEvent.WORLD_CHANGED) {
            markStale();
            return;
        }
        refresh();
        if (e.getChangeType() == IModelChangedEvent.CHANGE) {
            Object obj = e.getChangedObjects()[0];
            if (obj instanceof ICharacterBase) {
                String property = e.getChangedProperty();
                if (property != null && property.equals(getPage().getTGREditor().getTitleProperty()))
                    getPage().getTGREditor().updateTitle();
            }
        }
    }

    public void refresh() {
        ICharacterModelBase model = (ICharacterModelBase) getPage().getTGREditor().getContextManager().getAggregateModel();
        ICharacterBase characterBase = model.getCharacterBase();
        fAgeEntry.setValue(characterBase.getSketch().getAge(), true);
        super.refresh();
    }

    public void cancelEdit() {
        fAgeEntry.cancelEdit();
        super.cancelEdit();
    }

    public void dispose() {
        removeListeners();
        super.dispose();
    }

    protected void removeListeners() {
        IBaseModel model = getPage().getModel();
        if (model instanceof IModelChangeProvider)
            ((IModelChangeProvider) model).removeModelChangedListener(this);
    }

    protected void addListeners() {
        IBaseModel model = getPage().getModel();
        if (model instanceof IModelChangeProvider)
            ((IModelChangeProvider) model).addModelChangedListener(this);
    }

    public boolean canPaste(Clipboard clipboard) {
        Display d = getSection().getDisplay();
        return (d.getFocusControl() instanceof Text);
    }

}
